
#pragma once

#include <WinDef.h>

#include "Core\Shader.h"

struct ID3D10Blob;
struct ID3D11Buffer;
struct ID3D11InputLayout;
struct ID3D11PixelShader;
struct ID3D11VertexShader;

class Light;
class Material;
class Matrix4x4;
class Vector4;

class MPMLShader : public Shader
{
public:
	MPMLShader();
	~MPMLShader();

	// Management.
	//-----------------------------------------------
	// System memory.
	static BOOL IsLoaded();

	static BOOL Load();
	static VOID Unload();

	// Renderer.
	BOOL IsBinded() CONST;

	BOOL Bind();
	VOID Unbind();

	VOID Enable();

	// Parametrization.
	//-----------------------------------------------
	BOOL SetFrameBuffer(CONST Vector4& position,
					    CONST Matrix4x4& world,
					    CONST Matrix4x4& view,
					    CONST Matrix4x4& projection);

	BOOL SetLightBuffer(CONST Light& light,
						CONST Matrix4x4& world);

	BOOL SetMaterialBuffer(CONST Material& material);

protected:
	MPMLShader(CONST MPMLShader&);
	MPMLShader& operator = (CONST MPMLShader&);

private:
	// Shader constant buffers typedefs.
	//-----------------------------------------------
	typedef struct
	{
		FLOAT position[4];
		FLOAT world[16];
		FLOAT view[16];
		FLOAT projection[16];
	} FrameBuffer;

	typedef struct
	{
		FLOAT position[4];
		FLOAT direction[3];
		FLOAT angle;
		FLOAT radius;
		FLOAT ambient[3];
		FLOAT diffuse[3];
		FLOAT constant_attenuation;
		FLOAT specular[3];
		FLOAT linear_attenuation;
		FLOAT quadratic_attenuation;
		FLOAT exponent;
		BYTE  padding[2 * 4];
	} LightBuffer;

	typedef struct
	{
		FLOAT opacity;
		FLOAT ambient[3];
		FLOAT shininess;
		FLOAT diffuse[3];
		FLOAT specular[3];
		BYTE  padding[4];
	} MaterialBuffer;

private:
	// Attributes.
	//-----------------------------------------------
	// Common data.
	static ID3D10Blob*	 s_vshader_buffer;
	static ID3D10Blob*	 s_pshader_buffer;

	static BOOL			 s_loaded;

	// Handler.
	ID3D11InputLayout*   m_layout;
	ID3D11VertexShader*  m_vshader;
	ID3D11PixelShader*   m_pshader;

	BOOL				 m_binded;
	
	// Mapped buffers.
	ID3D11Buffer*		 m_frame_buffer;
	ID3D11Buffer*		 m_light_buffer;
	ID3D11Buffer*        m_material_buffer;
};

